#include "tcp_socket.h"
#include <iostream>

using namespace std;

tcp_socket::tcp_socket():sockfd(0), listfd(0), isserver(true)
{
}

tcp_socket::~tcp_socket()
{
	if (isserver)
	{
		close(sockfd);
		cout << "close: " << sockfd << endl;
	}

	close(listfd);
	cout << "close: " << listfd << endl;
}

bool tcp_socket::socket(int domain, int type, int protocol)
{
	listfd = ::socket(domain, type, protocol);
	if (listfd < 0)
		return false;

	int flag = 0;
	setsockopt(listfd, SOL_SOCKET, SO_REUSEADDR, (const char *)&flag, sizeof(flag));

	return true;
}

bool tcp_socket::bind(char *ip, int port)
{
	struct sockaddr_in svraddr;
	svraddr.sin_family = AF_INET;
	svraddr.sin_port = htons(port);
	if (inet_pton(AF_INET, ip, &svraddr.sin_addr) < 0)
		return false;

	int ret = 0;
	ret = ::bind(listfd, (struct sockaddr *)&svraddr, sizeof(svraddr));
	if (ret < 0)
		return false;

	return true;
}

bool tcp_socket::listen()
{
	if (::listen(listfd, 10) < 0)
		return false;

	return true;
}

bool tcp_socket::accept(struct sockaddr_in *cliaddr)
{
	socklen_t addrlen = sizeof(struct sockaddr_in);

	sockfd = ::accept(listfd, (struct sockaddr *)cliaddr, &addrlen);
	if (sockfd < 0)
		return false;

	return true;
}

bool tcp_socket::connect(char *ip, int port)
{
	struct sockaddr_in svraddr;
	svraddr.sin_family = AF_INET;
	svraddr.sin_port = htons(port);

	isserver = false;

	if (inet_pton(AF_INET, ip, &svraddr.sin_addr) < 0)
		return false;

	if (::connect(listfd, (struct sockaddr *)&svraddr, sizeof(svraddr)) < 0)
			return false;

	return true;
}

int tcp_socket::recv(char *buf, int len, int flag)
{
	return ::recv(sockfd, buf, len, flag);
}

int tcp_socket::send(char *buf, int len, int flag)
{
	return ::send(sockfd, buf, len, flag);
}

